;;; init-rss.el --- Rss reader configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:

(with-eval-after-load 'elfeed
  (defun ctrlwei/get-elfeed-sub-tags (elfeed-tags)
    "Return elfeed sub level tag list(when tag name first letter is
lowercase letter, it belongs to second level)."
    (let ((tags elfeed-tags))
      (dolist (tag (ctrlwei/get-elfeed-header-tags elfeed-tags))
        (setq tags (remove tag tags)))
      tags))

  (defun ctrlwei/get-elfeed-header-tags (elfeed-tags)
    "Return elfeed first level tag list(when tag name first letter is
uppercase letter, it belongs to first level)."
    (let ((case-fold-search nil)
          header-tags)
      (dolist (tag elfeed-tags)
        (if (string-match-p "[[:upper:]]" (symbol-name tag))
              (add-to-list 'header-tags tag)))
      header-tags))

  (defun generate-func-get-feed-tag (tags)
    "Return a procedure, when run this procedure,
it will cyclic output every member in TAGS.
Please make sure TAGS is non-nil."
    (let ((head 0)
          (tail (1- (length tags)))
          (current-pos -1))
      (lambda (&optional get-previous)
        (if get-previous
            (progn
              (if (or (< current-pos 0) (= current-pos head))
                  (setq current-pos tail)
                (setq current-pos (1- current-pos)))
              (nth current-pos tags))
          (progn
            (if (or (< current-pos 0) (= current-pos tail))
                (setq current-pos head)
              (setq current-pos (1+ current-pos)))
            (nth current-pos tags))))))

  (defun ctrlwei/elfeed-filter-include-tag ()
    "Select tags to include `+'.
 The function reads the tags from the elfeed db."
    (interactive)
    (let ((filtered-tag (completing-read "Select Tags: " (elfeed-db-get-all-tags))))
      (setq elfeed-search-filter (concat "+unread +" filtered-tag))
      (elfeed-search-update--force)))


  (setq elfeed-db-directory "~/.cache/elfeed/")
  (setq elfeed-search-filter "+unread ")
  (setq elfeed-feeds '(("http://planet.emacslife.com/atom.xml" Emacs emacsen)
                       ("http://www.dongwm.com/atom.xml" Python dongwm)
                       ("https://www.planetpython.org/rss20.xml" Python planetpython)
                       ("https://news.ycombinator.com/rss" News hacker_news)
                       ("https://www.omgubuntu.co.uk/feed" News omgubuntu)
                       ("https://forum.manjaro.org/c/announcements.rss" News manjaro_news)
                       ("https://www.solidot.org/index.rss" News qike)
                       ("https://www.oschina.net/news/rss" News oschina_news)
                       ("https://github.com/ctrl2wei.private.atom?token=AhZPCU2VkxN4vzqJRlb7K63BjZclEk9Sks66E77awA==" Github github_sub_news)
                       ("https://manateelazycat.github.io/feed.xml" Blog lazycat)
                       ("https://zilongshanren.com/index.xml" Blog zilongshanren)
                       ("http://blog.binchen.org/rss.xml" Blog chenbin)
                       ("https://www.linux.com/feed/" Linux linuxcom)
                       ("https://nullprogram.com/feed/" Blog wellons)
                       ("https://emacsredux.com/atom.xml" Blog emacsredux)
                       ("https://liujiacai.net/atom.xml" Blog liujiacai)
                       ("https://thisweek.gnome.org/index.xml" Blog gnome)
                       ("https://dotfyle.com/this-week-in-neovim/rss.xml" Blog neovim)
                       ("https://github.com/neovim/neovim/commits/master/runtime/doc/news.txt.atom" News neovim)
                       ("https://pointieststick.com/feed/" Blog kde)))

  (setq elfeed-all-tags (delete 'unread (elfeed-db-get-all-tags)))
  (setq get-feed-sub-tag (generate-func-get-feed-tag (ctrlwei/get-elfeed-sub-tags elfeed-all-tags)))
  (setq get-feed-header-tag (generate-func-get-feed-tag (ctrlwei/get-elfeed-header-tags elfeed-all-tags)))

  (defun call-get-next-feed (get-tag-fuc &optional reverse)
    (interactive)
    (elfeed-search-set-filter (concat "+unread +" (symbol-name (funcall get-tag-fuc reverse))))
    (elfeed-search-first-entry))

  (defun ctrlwei/elfeed-toggle-unread-tag ()
    (interactive)
    (if (string-match-p "+unread" elfeed-search-filter)
        (elfeed-search-set-filter (replace-regexp-in-string "+unread" "" elfeed-search-filter))
      (elfeed-search-set-filter (concat "+unread" elfeed-search-filter))))

  (define-key-with-arg elfeed-search-mode-map (kbd "n") call-get-next-feed get-feed-sub-tag)
  (define-key-with-arg elfeed-search-mode-map (kbd "N") call-get-next-feed get-feed-header-tag)
  (define-key-with-arg elfeed-search-mode-map (kbd "p") call-get-next-feed get-feed-sub-tag t)
  (define-key-with-arg elfeed-search-mode-map (kbd "P") call-get-next-feed get-feed-header-tag t)

  (define-key elfeed-search-mode-map (kbd "j") #'next-line)
  (define-key elfeed-search-mode-map (kbd "k") #'previous-line)
  (define-key elfeed-show-mode-map (kbd "j") #'next-line)
  (define-key elfeed-show-mode-map (kbd "k") #'previous-line)
  (define-key elfeed-search-mode-map (kbd "F") #'ctrlwei/elfeed-filter-include-tag)
  (define-key elfeed-search-mode-map (kbd "f") #'ctrlwei/elfeed-toggle-unread-tag)

  (define-key elfeed-search-mode-map (kbd "q") (lambda () (interactive) (elfeed-db-save) (quit-window)))
  )

(global-set-key (kbd "M-g e") #'elfeed)

(provide 'init-rss)
;;; init-rss.el ends here
